/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package graf;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author marek
 */
public class Wierzcholek {

    private List<DefUse> defUse = new ArrayList<DefUse>();
    private List<WierzcholekPlusPlus> sasiedzi = new ArrayList<WierzcholekPlusPlus>();
    private int x;
    private int y;
    private boolean odwiedzony;
    private int odlStart;
    private int odlKoniec;
    private boolean poczatkowy;
    private boolean koncowy;

    public boolean isKoncowy() {
        return koncowy;
    }

    public void setKoncowy(boolean koncowy) {
        this.koncowy = koncowy;
    }

    public boolean isPoczatkowy() {
        return poczatkowy;
    }

    public void setPoczatkowy(boolean poczatkowy) {
        this.poczatkowy = poczatkowy;
    }


    public int getOdlKoniec() {
        return odlKoniec;
    }

    public void setOdlKoniec(int odlKoniec) {
        this.odlKoniec = odlKoniec;
    }

    public int getOdlStart() {
        return odlStart;
    }

    public void setOdlStart(int odlStart) {
        this.odlStart = odlStart;
    }

    public List<DefUse> getDefUse() {
        return defUse;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getNumer() {
        return numer;
    }

    public void setNumer(int numer) {
        this.numer = numer;
    }
    private int numer;

    public Wierzcholek() {
        this.odwiedzony = false;
        this.odlStart = this.odlKoniec = -1;
    }

    public List<WierzcholekPlusPlus> getSasiedzi() {
        return sasiedzi;
    }

    public boolean isOdwiedzony() {
        return odwiedzony;
    }

    public void setOdwiedzony(boolean odwiedzony) {
        this.odwiedzony = odwiedzony;
    }

    public boolean czyZawieraSasiada(Wierzcholek wK) {
        for(WierzcholekPlusPlus wpp : getSasiedzi()){
            if(wpp.getWierzcholek().getNumer() == wK.getNumer()){
                return true;
            }
        }
        return false;
    }

    public void dodajUzycie(String text) {
        for(DefUse du : defUse){
            if(du instanceof Uzycie && du.getZmienna().equals(text)){
                return;
            }
        }
        defUse.add(new Uzycie(text));
    }

    public void dodajDefinicje(String text) {
        for(DefUse du : defUse){
            if(du instanceof Definicja && du.getZmienna().equals(text)){
                return;
            }
        }
        defUse.add(new Definicja(text));
    }

    public void dodajUzycie(Integer kon, String text) {
        for(WierzcholekPlusPlus wpp : getSasiedzi()){
            if(wpp.getWierzcholek().getNumer() == kon){
                for(DefUse du : wpp.getDefUse()){
                    if(du instanceof Uzycie && du.getZmienna().equals(text)){
                        return;
                    }
                }
                wpp.getDefUse().add(new Uzycie(text));
                return;
            }
        }
    }

    public void dodajDefinicje(Integer kon, String text) {
        for(WierzcholekPlusPlus wpp : getSasiedzi()){
            if(wpp.getWierzcholek().getNumer() == kon){
                for(DefUse du : wpp.getDefUse()){
                    if(du instanceof Definicja && du.getZmienna().equals(text)){
                        return;
                    }
                }
                wpp.getDefUse().add(new Definicja(text));
                return;
            }
        }
    }

    public int distanceToNearestEndNode(Sciezka path, Graf g){
	if(path == null){
            path = new Sciezka();
        }
	if(g.isKoncowy(this)){
            int dist = path.edgeCount() + 1;
            return dist;
	}
	if(path.czyNaSciezce(this)){
            return -1;
	}
        path.dodajNaKoniec(this);
	int minDist = -1;
	for(WierzcholekPlusPlus wP: this.getSasiedzi()){
            int dist = wP.getWierzcholek().distanceToNearestEndNode(new Sciezka(path), g);
            if(dist > minDist){
                minDist = dist;
            }
	}
	return minDist;
    }

    public int distanceToNearestStartNode(Sciezka path, Graf g){
	if(path == null){
            path = new Sciezka();
        }
	if(g.isPoczatkowy(this)){
            int dist = path.edgeCount() + 1;
            return dist;
	}
	if(path.czyNaSciezce(this)){
            return -1;
	}
	path.dodajNaKoniec(this);
	int minDist = -1;
        ArrayList<Wierzcholek> sasiedziWsteczni = new ArrayList<Wierzcholek>();
        for(Wierzcholek w: g.getWierzcholki()){
            if(w.czyZawieraSasiada(this)){
                sasiedziWsteczni.add(w);
            }
        }
	for(Wierzcholek ww: sasiedziWsteczni){
            int dist = ww.distanceToNearestStartNode(new Sciezka(path), g);
                if(dist > minDist){
                    minDist = dist;
                }
	}
        return minDist;
    }
}
